/**
 * 树控件
 * @author Ly
 * @version 1.0a
 */
/**
 * Ly.Tree的构造函数
 * @param {Object} container 树的容器对象,默认为body对象
 * @param {Object} config 树的配置参数
 * config = {
     themes : 'default',
     baseCls : 'ly-tree',
     autoCollapse : false,            // 是否单击节点时自动折叠
     icon : [{ level : 0, openIcon : 'open.gif', closeIcon : 'close.gif'}],
     hiddenIcon : false,              // 隐藏图标
     events : {
         onclick : function(obj) {
             alert(obj.prototype.id); // 返回值为当前节点对象,取节点信息为obj.prototype的对象集合
         },
         ondblclick : function(obj) {
         }
     }
 }
 */
Ly.Tree = function(container, config) {
    var _this = this;
    config = config || {};
    
    // 配置信息
    this.config = {
        /**
         * 承載Tree組件的窗口對象
         * @type Object
         */
        container : container || document.body,
        /**
         * Tree組件的主題名稱
         * @type String
         */
        themes : config.themes || 'default',
        /**
         * 作用在組件上的样式
         * @type String
         */
        baseCls : config.baseCls || 'ly-tree',
        /**
         * 是否支持自動單擊標題自動折疊節點
         * @type Boolean 默認為false
         */
        autoCollapse : config.autoCollapse || false,
        /**
         * Tree組件中標記節點打開與關閉的圖標，
         * level=-1作用所有節點的樣式
         * level=0代表第一層節點，依類類推
         * @type Array
         */
        icon : config.icon || [
            {
                level     : 0,
                openIcon  : Ly.getPath() + 'images/' + this.themes + '/open.gif',
                closeIcon : Ly.getPath() + 'images/' + this.themes + '/close.gif'
            }
        ],
        /**
         * 是否隐藏图标
         * @type Boolean
         */
        hiddenIcon : config.hiddenIcon || false,
        /**
         * 事件對象，例如：{onclick : function(){}, ondblclick : function() {}}
         * @type Object
         */
        events : config.events || {},
        /**
         * 節點數組,存放所有的節點信息,給節點對象擴展以下屬性
         * id,name,path,data,state,parentNode,hasChildNodes,level
         * @type Array
         */
        nodes : [],
        /**
         * 当前节点
         * @type Object
         */
        currentNode : null
    };
    
    // 私有方法
    this.private = {
        /**
         * 獲取所有的子節點對象
         * @param {Object} obj 要獲取子節點的節點對象
         * @return {Array} 由子節點組成的數據
         */
        childNodes : function(obj) {
            var cn = [],
                c = this.config,
                nl = c.nodes.length;
            
            for (var i = 0; i < nl; i++) {
                if (c.nodes[i].parentNode === obj) {
                    cn.push(c.nodes[i]);
                }
            }
            return cn;
        },
        /**
         * 獲取相應的圖標
         * @param {Number} index 0/1,0代表一行中的第一個圖標，１代表一行中的第二個圖標
         * @param {Number} state 0/1, 0代表折疊狀態,1代表展開狀態
         * @param {Number} level 當前節點的深度,基數為零
         * @return {String} 圖標路徑
         */
        getIcon : function(index, state, level) {
            var il,
                icon = _this.config.icon || [],
                openIcon = Ly.getPath() + 'images/' + _this.config.themes + '/tree/open.gif',
                closeIcon = Ly.getPath() + 'images/' + _this.config.themes + '/tree/close.gif';
            
            il = icon.length;
            for (var i = 0; i < il; i++) {
                if (icon[i].level == -1 || icon[i].level == level) {
                    openIcon  = icon[i].openIcon;
                    closeIcon = icon[i].closeIcon;
                }
            }
            
            if (!index) {
                return Ly.getPath() + 'images/' + _this.config.themes + (state ? '/tree/minus.gif' : '/tree/plus.gif');
            } else {
                for (var i = 0; i < il; i++) {
                    if (icon[i].level == level) {
                        return state ? icon[i].openIcon : icon[i].closeIcon;
                    }
                }
                return state ? openIcon : closeIcon;
            }
        },
        /**
         * 设置为当前节点
         * @param {Object} obj 当前节点对象
         */
        settingSelected : function(obj) {
            with (Ly.$(obj.prototype.id + '-title').firstChild.firstChild.style) {
                backgroundColor = '#335EA8';
                color = '#FFFFFF';
            }
            _this.config.currentNode = obj;
        },
        /**
         * 將節點信息保存
         * @param {Object} obj 要保存的節點對象
         */
        save : function(obj) {
            var n = _this.config.nodes,
                nl = n.length;
            
            if (obj.parentNode === document.body) {
                n.push(obj);
            } else {
                for (var i = 0; i < nl; i++) {
                    if (n[i] === obj.prototype.parentNode) {
						n[i].prototype.hasChildNodes = true;
                        break;
                    }
                }
                n.push(obj);
            }
        },
        
        isChild : function(pn /* parentNode */, cn /* childNode */) {
            if (pn.prototype.parentNode) {
                return false;
            } else {
                if (pn.prototype.parentNode === cn) {
                    return true;
                } else {
                    return _this.private.isChild(pn, cn);
                }
            }
        },
        /**
         * 初始化節點狀態
         * @param {Object} obj 要初始化狀態的節點對象
         * @return {Boolean} 初始化狀態是否成功
         */
        initState : function(obj) {
            var op  = obj.prototype;
            var ops = op.state;
            
            if (obj.prototype.keepState != '') {
                ops = obj.prototype.keepState == 'open' ? 'open' : 'close';
            }
            
            if (op.hasChildNodes) {
                with (Ly.$(op.id + '-icon1')) {
                    innerHTML = '<img src="' + this.getIcon(0, 0, op.level) + '" border=0 />';
                    style.visibility = "visible";
                }
            }
            
            if (ops == 'open') {
                obj.nextSibling.style.display = 'block';
                Ly.$(op.id + '-icon1').innerHTML = '<img src="' + this.getIcon(0, 1, op.level) + '" border=0 />';
                if (Ly.isEmpty(op.icons.open)) {    // 使用公共圖標
                    Ly.$(op.id + '-icon2').innerHTML = '<img src="' + this.getIcon(1, 1, op.level) + '" border=0 />';
                } else {    // 使用私有圖標
                    Ly.$(op.id + '-icon2').innerHTML = '<img src="' + op.icons.open + '" border=0 />';
                }
            } else {
                obj.nextSibling.style.display = 'none';
                Ly.$(op.id + '-icon1').innerHTML = '<img src="' + this.getIcon(0, 0, op.level) + '" border=0 />';
                if (Ly.isEmpty(op.icons.close)) {    // 使用公共圖標
                    Ly.$(op.id + '-icon2').innerHTML = '<img src="' + this.getIcon(1, 0, op.level) + '" border=0 />';
                } else {    // 使用私有圖標
                    Ly.$(op.id + '-icon2').innerHTML = '<img src="' + op.icons.close + '" border=0 />';
                }
            }
            // 設置父節點的樣式
            var p = op.parentNode;
            if (!p || p === _this.config.container) {
                return;
            } else {
                // 判定父節點原來的狀態是否為打開
                if (p.prototype.state == 'close' && p.prototype.keepState == '') {
                    Ly.$(p.prototype.id + '-icon1').innerHTML = '<img src="' + this.getIcon(0, 0, p.prototype.level) + '" border=0 />';
                }
                Ly.$(p.prototype.id + '-icon1').style.visibility = 'visible';
            }
        },
        /**
         * 初始化節點事件
         * @param {Object} obj 要初始化事件的節點對象
         * @param {Object} events 事件對象
         * events = {
             onclick : function() {}
         }
         * @return {Boolean} 初始化事件是否成功
         */
        initEvents : function(obj, events) {
            var o = Ly.$(obj.prototype.id + '-title').firstChild.firstChild;
            o.prototype = {};
            // 拷貝obj的屬性
            for (var p in obj.prototype) {
                o.prototype[p] = obj.prototype[p];
            }
            // 添加默認事件
            Ly.addEvent('onmouseover',
                function(obj) {
                    obj.style.borderBottom = '1px #000000 solid';
                },
            o);
            Ly.addEvent('onmouseout',
                function(obj) {
                    obj.style.borderBottom = 'none';
                },
            o);
            Ly.addEvent('onclick',
                function(obj) {
                    if (_this.config.currentNode != null) {
                        var op = obj.prototype,
                            cn = Ly.$(_this.config.currentNode.prototype.id + '-title');
                        // 取消原选中节点的样式
                        if (cn != null) {
                            with (cn.firstChild.firstChild.style) {
                                backgroundColor = '';
                                color = '';
                                cssText += op.style;
                            }
                        }
                    }
                    // 设置当前节点样式
                    _this.private.settingSelected(obj);
                },
            o);
			
			// 當前節點對象作為superNode返回。
			o.prototype.superNode = obj;
            
            // 給第一個圖標添加事件
            var icon = Ly.$(obj.prototype.id +'-icon1');
            icon.prototype = {};
            // 拷貝obj的屬性
            for (var p in obj.prototype) {
                icon.prototype[p] = obj.prototype[p];
            }
            Ly.addEvent('onclick', this.updateState, icon);
			
			// 给展开与折叠标签添加公共事件
			if (obj.prototype.respondPublicEvents) {
				for (var p in _this.config.events) {
					Ly.addEvent(p, _this.config.events[p], icon);
				}
			}
			
            // 添加用戶事件
            for(var p in events) {
                Ly.addEvent(p, events[p], o);
				if (obj.prototype.respondUserEvents) {
					Ly.addEvent(p, events[p], icon);
				}
            }
        },
        /**
         * 更新節點狀態
         * @param {Object} obj 觸發事件的節點子對象
         * @param {String} source 事件的來源，是通過單擊標題觸發，還是通過單擊圖標觸發，省略則為通過單擊圖標觸發
         */
        updateState : function(obj, source) {
            // 查找當前節點
            var cn /* currentNode */,
                c  = _this.config,
                n  = c.nodes,
                nl = n.length,
                op = obj.prototype;
            
            for (var i = 0; i < nl; i++) {
                if (n[i].prototype.id == obj.prototype.id) {
                    cn = n[i];
                    break;
                }
            }
            
			//alert(source);
            // 判斷是否需要執行展開或折疊操作
            if (source == 'title' && !c.autoCollapse && cn.prototype.state == 'open') { return; }
            
            if (_this.config.currentNode != null) {
                var n = _this.config.nodes;
                var nl = n.length;
                
                for (var i = 0; i < nl; i++) {
                    if (n[i].prototype.level == op.level && !n[i].prototype.hasChildNodes) {
                        n[i].prototype.state = 'close';
                        n[i].nextSibling.style.display = 'none';
						
                        Ly.$(n[i].id + '-icon1').innerHTML = '<img src="' + _this.private.getIcon(0, 0, n[i].prototype.level) + '" border=0 />';
                        if (Ly.isEmpty(n[i].prototype.icons.close)) {
                            Ly.$(n[i].id + '-icon2').innerHTML = '<img src="' + _this.private.getIcon(1, 0, n[i].prototype.level) + '" border=0 />';
                        } else {
                            Ly.$(n[i].id + '-icon2').innerHTML = '<img src="' + n[i].prototype.icons.close + '" border=0 />';
                        }
                    }
                }
            }
			
            cn.prototype.state = cn.prototype.state == 'close' ? 'open' : 'close';
            _this.private.initState(cn);
        },
        /**
         * 擴展節點
         * @param {Object} obj 要進行擴展的節點對象
         * @param {Object} config 擴展配置信息
         */
        extendNode : function(obj, config) {
        }
    };
};
Ly.Tree.prototype = {
    version : '1.0a',
    /**
     * 添加節點
     * @param {Object} parent 父節點
     * @param {Object} config 節點信息
     *  config = {
         id : 'ly-tree-0',                      // (可省略)節點ID,若省略系統會自動生成唯一ID
         name : 'demo',                         // 節點名稱,即顯示的內容
         data : 1234,                           // (可省略)此節點附帶的數據
         style : '',                            // 當前節點的樣式
         keepState : '',                        // 保持的状态，默认空，即不保持
         disablePE : false,                     // 禁用公共事件，默認false
         openChilds : false,                    // 是否展開子節點，默認false
		 selected   : false,                    // 是否選中此節點，當openChilds為true是有效
		 hasChildNodes : false,                 // 是否拥有子节点。
		 respondUserEvents : false,             // 标识展开与折叠的图标是否响应用户事件
		 respondPublicEvents : false,           // 标识展开与折叠的图标是否响应公共事件
         disablePE : false,                     // 禁用公共事件
		 position : 'first',                    // 節點的插入位置，默認last
         icons : {
             open : '',                         // 展開時的圖標,為空則使用默認圖標
             close : ''                         // 折疊後的圖標,為空則使用默認圖標
         },
         events : {                             // (可省略)當前節點所獨有的事件
             onclick : function(obj) {}
         },
         extend : {                             // (可省略)擴展節點內容
             left : '',
             right : ''
         }
     }
     * @return {Object} obj 当前节点对象,例如取id   var id = obj.prototype.id;
        obj.prototype = {
            id                                 // 节点ID
            name                               // 节点名称
            path                               // 节点路径,用/分隔
            data                               // 节点的附加信息,若添加节点时没有则为空
			
			superNode                          // 當前節點對象

            state                              // 节点状态,打开(open)或关闭(close)
            parentNode                         // 当前节点的父节点对象
            hasChildNodes                      // 是否有子节点
            level                              // 当前节点的深度,基数0
        }
     */
    add : function(parent, config) {
        if (arguments.length != 2) {
            alert('add方法需要两个参数!');
            return false;
        }
        
        config.name     = config.name || '';
        config.icons    = config.icons || {};
		config.extend   = config.extend || {};
		config.position = config.position || 'last';
        
        if (config.name == '') {
            alert('config参数的name属性不可为空!');
            return false;
        }
        
        parent.prototype       = parent.prototype || {};
        parent.prototype.path  = parent.prototype.path || '';
        parent.prototype.level = parent.prototype.level || 0;
        
        var
            c /* config */ = {
                id               : config.id || 'ly-tree-' + Ly.getCount(),
                name             : config.name,
                level            : parent.prototype.level + 1,
                style            : config.style || '',
                openChilds       : config.openChilds || false,
				hasChildNodes    : config.hasChildNodes || false,
				respondUserEvents : config.respondUserEvents || false,
				respondPublicEvents : config.respondPublicEvents || false,
				selected         : config.selected || false,
                disablePE        : config.disablePE || false,
                keepState        : config.keepState || '',
                data             : config.data || '',
                events           : config.events || {},
                extend           : config.extend || {}
            },
            n /* node */ = Ly.createElement('div', {
                id    : c.id,
                cls   : this.config.baseCls,
                style : c.style
            }),
            cnc /* childNodesContainer */ = Ly.createElement('div', {cls : 'ly-tree-child'});
        
		c.extend = {
			left  : config.extend.left || '',
			right : config.extend.right || ''
		};
        if (parent === this.config.container) {
            parent.appendChild(n);
            parent.appendChild(cnc);
        } else {
            switch (config.position.toLowerCase()) {
				case 'first':
					parent.nextSibling.insertBefore(cnc, parent.nextSibling.firstChild);
					parent.nextSibling.insertBefore(n, parent.nextSibling.firstChild);
					break;
				default :
					parent.nextSibling.appendChild(n);
    		        parent.nextSibling.appendChild(cnc);
					break;
				
			}
        }
        
        n.innerHTML = '<table border="0" width="100%" cellspacing="0" cellpadding="0">' +
            '<tr>' +
            '<td id="' + c.id + '-icon1" class="ly-tree-icon" style="visibility:hidden;">' +
            '<img src="' + this.private.getIcon(0, 0, c.level) + '" border="0">' +
            '</td>' +
            '<td id="' + c.id + '-icon2" class="ly-tree-icon" style="display:' + (this.config.hiddenIcon ? 'none' : '') + ';">' +
            '<img src="' + this.private.getIcon(1, 0, c.level) + '" border="0">' +
            '</td>' +
            '<td id="' + c.id + '-left" class="ly-tree-left">' + c.extend.left + '</td>' +
            '<td id="' + c.id + '-title" class="ly-tree-title">' +
            '<div><span>' + c.name + '</span></div>' +
            '</td>' +
            '<td id="' + c.id + '-right" class="ly-tree-right">' + c.extend.right + '</td>' +
            '</tr>' +
            '</table>';
        
        n.prototype = {
            id            : c.id,
            name          : c.name,
            path          : parent.prototype.path + '/' + c.name,
            data          : c.data,
            state         : (c.openChilds ? 'open' : 'close'),
            keepState     : c.keepState,
            icons         : {
                open  : config.icons.open,
                close : config.icons.close
            },
            parentNode          : parent,
            hasChildNodes       : c.hasChildNodes,
			respondUserEvents   : c.respondUserEvents,
			respondPublicEvents : c.respondPublicEvents,
            level               : c.level,
			childNodesContainer : cnc   // 指向子节点容器
        };
        
        var o = Ly.$(n.prototype.id + '-title').firstChild.firstChild;
        o.prototype = {};
        // 拷貝n的屬性
        for (var p in n.prototype) {
            o.prototype[p] = n.prototype[p];
        }

        // 添加公共事件
        if (!c.disablePE) {
            var _this = this;
            for(var p in this.config.events) {
                Ly.addEvent(p, this.config.events[p], o);
            }
            Ly.addEvent('onclick',
                        function(obj) {
                            _this.private.updateState(obj, 'title');
                        }, o);
        }
        this.private.initEvents(n, config.events);
        
        this.private.save(n);
        this.private.initState(n);
        if (c.openChilds && c.selected) { this.private.settingSelected(n); }
        //this.private.extendNode(n, config.extends);
        
        return n;
    },
    /**
     * 修改節點
     * @param {String} id 原節點對象
     * @param {Object} config 新的節點信息
     */
    modify : function(id, config) {
    },
    /**
     * 刪除節點
     * @param {Object} obj 要刪除子節點的對象
     */
    del : function(obj) {
		var nodes = this.config.nodes,
			p = obj.prototype.parentNode,
			index = -1,
			count = -1;
		
		for (var i = nodes.length - 1; i >= 0; --i) {
			if (nodes[i].prototype.parentNode === p) {
				count++;
			}
			if (nodes[i] === p) {
				index = i;
			}
			if (nodes[i] === obj) {
				nodes[i].parentNode.removeChild(nodes[i].nextSibling);
				nodes[i].parentNode.removeChild(nodes[i]);
				nodes[i] = null;
				nodes.splice(i, 1);
			}
		}
		
		// 更新父節點的hasChildNodes屬性
		if (index > -1 && count < 1) {
			nodes[index].prototype.hasChildNodes = false;
		}
		
    },
    /**
     * 刪除子節點
     * @param {Object} obj 要刪除子節點的對象
	 * @param {Boolean} flag 是否遞迴調用，調用時省略此參數
     */
    delChildNodes : function(obj, flag) {
        var
            parentNode = obj.prototype.parentNode,
            id = obj.prototype.id,
            nodes = this.config.nodes;
        
        for (var i = nodes.length - 1; i > -1; --i) {
			if (nodes[i].prototype.parentNode === obj) {
				if (nodes[i].prototype.hasChildNodes) {
					this.delChildNodes(nodes[i], true);
				}
				this.del(nodes[i]);
			}
		}
		
		if (flag) { return; }
        Ly.get(id + '-icon1').style.visibility = 'hidden';
        obj.prototype.hasChildNodes = false;
    },
    /**
     * 刪除樹
     */
    delTree : function() {
		this.config.container.innerHTML = '';
		return this;
    },
    /**
     * 移動節點到指定的節點,不可將父節點移動或復制到子節點中
     * @param {String} src 要移動的節點
     * @param {String} des 目標節點
     */
    move : function(src, des) {
    },
    /**
     * 復制節點到指定的節點
     * @param {String} src 源節點
     * @param {String} des 目標節點
     */
    copy : function(src, des) {
    },
    /**
     * 獲取節點信息
     * @param {String} id 節點唯一ID
     * @return {Object} 節點信息對象
     */
    get : function(id) {
        var n = this.config.nodes;
        
        for (var i = 0; i < n.length; i++) {
            if (n[i].prototype.id == id) {
                return n[i];
            }
        }
        return null;
    },
    /**
     * 自動選擇一個節點
     * @param {Object} tree 樹組件的實例對象
     * @param {Object} obj1 要自動選擇的節點對象
     * @param {Object} obj2 需要執行動作的對象
     */
    autoSelect : function(tree /* Object */, obj1 /* Object */, obj2 /* Object */) {
        if (obj1.prototype.parentNode !== this.config.container) {
            this.autoSelect(tree, obj1.prototype.parentNode);
        }
        tree.private.updateState(obj1, 'title');
        
        if (obj2) {
            if (tree.config.currentNode != null) {
                var op = obj2.prototype;
                var cn = Ly.$(tree.config.currentNode.prototype.id + '-title');
                // 取消原选中节点的样式
                if (cn != null) {
                    with (cn.firstChild.firstChild.style) {
                        backgroundColor = '';
                        color = '';
                        cssText += op.style;
                    }
                }
            }
            // 设置当前节点样式
            tree.private.settingSelected(obj2);
        }
    },
    /**
     * 擴展節點
     * @param {String} id 要擴展的節點
     * @param {String} position 擴展位置,left(default)/right
     * @param {String} str 要添加的標籤代碼
     */
    extend : function(id, position, str) {
    },
    /**
     * 給節點添加事件
     * @param {Object} events 事件集合
     */
    addEvent : function(events) {
    }
};